package com.songlanyun.modules.coupon.service.impl.shopcoupon;

import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.coupon.model.dto.SelectShopCouponDTO;
import com.songlanyun.modules.coupon.model.dto.SelectShopCouponGoodsDTO;
import com.songlanyun.modules.coupon.model.vo.CouponEntityVo;
import com.songlanyun.modules.coupon.model.vo.CouponReceiveRecordVo;
import com.songlanyun.modules.coupon.service.CouponReceiveRecordService;
import com.songlanyun.modules.coupon.service.ISelectShopCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SelectShopCouponServiceImpl implements ISelectShopCouponService {
    @Autowired
    private CouponReceiveRecordService couponReceiveRecordService;

    @Override
    public List<CouponReceiveRecordVo> selectShopCoupons(Long userId, SelectShopCouponDTO dto) {
        List<CouponReceiveRecordVo> couponEntityVos = couponReceiveRecordService.loadMyShopCoupons(userId, dto.getShopId());
        List<CouponReceiveRecordVo> result = new ArrayList<>();
        for (CouponReceiveRecordVo couponEntityVo : couponEntityVos) {
            if (handle(dto, couponEntityVo)) {
                result.add(couponEntityVo);
            }
        }
        return result;
    }


    private boolean handle(SelectShopCouponDTO dto, CouponReceiveRecordVo couponEntityVo) {

        switch (dto.getMarketingType())
        {
            case 1:
                if(!couponEntityVo.isAdaptSecKill())
                {
                    return false;
                }
                break;
            case 2:
                if(!couponEntityVo.isAdaptGroupBuy())
                {
                    return false;
                }
                break;
            default:
                break;
        }
        if (couponEntityVo.getUniversal()) {
            if (generalCouponHandle(couponEntityVo, dto)) {
                return true;
            }
        } else {
            if (notGeneralCouponHandle(couponEntityVo, dto)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 非通用券算法
     *
     * @param couponEntityVo
     * @param dto
     * @return
     */
    private boolean notGeneralCouponHandle(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        if (!couponEntityVo.getHasThreshold()) {
            return noHasThresholdNotGeneral(couponEntityVo, dto);
        } else {
            return hasThresholdNotGeneral(couponEntityVo, dto);
        }
    }

    private boolean noHasThresholdNotGeneral(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        BigDecimal totalGoodsAmount = getTotalGoodsAmount(couponEntityVo,dto);
        if(totalGoodsAmount.compareTo(BigDecimal.ZERO)==0)
        {
            return false;
        }
        return true;
    }

    private BigDecimal getTotalGoodsAmount(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        Map<Long, SelectShopCouponGoodsDTO> childOrderGroups = dto.getGoodsList().stream().collect(Collectors.toMap(SelectShopCouponGoodsDTO::getGoodsId, vo -> vo));
        Set<Long> childOrderGoodsIds = childOrderGroups.keySet();
        List<Long> adaptGoodsIds = couponEntityVo.loadAdaptGoodsIds();
        if (couponEntityVo.getAdaptOrNo()) {
            childOrderGoodsIds.retainAll(adaptGoodsIds);

        } else {
            childOrderGoodsIds.removeAll(adaptGoodsIds);
        }

        BigDecimal totalGoodsAmount = BigDecimal.ZERO;
        for (Long goodsId : childOrderGoodsIds) {
            SelectShopCouponGoodsDTO submitChildOrderVo = childOrderGroups.get(goodsId);
            totalGoodsAmount = MathUtils.add(submitChildOrderVo.getTotalFactPrice(), totalGoodsAmount);
        }
        return totalGoodsAmount;
    }

    private boolean hasThresholdNotGeneral(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        BigDecimal totalGoodsAmount = getTotalGoodsAmount(couponEntityVo,dto);
        if(totalGoodsAmount.compareTo(BigDecimal.ZERO)==0)
        {
            return false;
        }
        if (totalGoodsAmount.compareTo(couponEntityVo.getThreshold()) < 0) {
            return false;
        }
        return true;
    }


    /**
     * 通用券算法
     *
     * @param couponEntityVo
     * @param dto
     * @return
     */
    private boolean generalCouponHandle(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        if (!couponEntityVo.getHasThreshold()) {
            return true;
        } else {
            return hasThresholdGeneral(couponEntityVo, dto);
        }
    }

    private boolean hasThresholdGeneral(CouponReceiveRecordVo couponEntityVo, SelectShopCouponDTO dto) {
        return dto.getTotalAmountNoCoupon().compareTo(couponEntityVo.getThreshold()) >= 0;
    }


}
